
package jtrimet;

import java.util.*;

@SuppressWarnings("serial")
public class Arrival implements java.io.Serializable
{
	public static final long ONE_MINUTE = (60 * 1000) /* 60,000 milliseconds equals 1 minute */;
	public static final long TWO_MINUTES = 2 * (ONE_MINUTE);
	public static final long FIVE_MINUTES = 5 * (ONE_MINUTE);
	public static final long TEN_MINUTES = 10 * (ONE_MINUTE);
	public static final long FIFTEEN_MINUTES = 15 * (ONE_MINUTE);
	public static final long THIRTY_MINUTES = 30 * (ONE_MINUTE);
	public static final long SIXTY_MINUTES = 60 * (ONE_MINUTE);
	
	private String locationId;
	private String block;
	private String direction;
	private String fullsign;
	private String shortsign;
	private String route;
	private String status;
	private Calendar estimatedStopTime;
	private Calendar scheduledStopTime;
	private boolean departed = false;
	private boolean detour = false;
	private BlockPosition blockPosition;
	
	public Arrival()
	{
		super();
	}

	public String getLocationId()
	{
		return locationId;
	}

	public void setLocationId(String locId)
	{
		this.locationId = locId;
	}

	public String getBlock()
	{
		return block;
	}

	public void setBlock(String b)
	{
		this.block = b;
	}

	public String getDirection()
	{
		return direction;
	}

	public void setDirection(String d)
	{
		this.direction = d;
	}

	public String getFullsign()
	{
		return fullsign;
	}

	public void setFullsign(String f)
	{
		this.fullsign = f;
	}

	public String getStatus()
	{
		return status;
	}

	public void setStatus(String status)
	{
		this.status = status;
	}

	public Calendar getEstimatedStopTime()
	{
		return estimatedStopTime;
	}

	/**
	 * 
	 * @return returns estimated stop time (if available); otherwise, returns scheduled stop time
	 * 
	 */
	public Calendar getStopTime()
	{
		if (getEstimatedStopTime() != null)
		{
			return getEstimatedStopTime();
		}
		else
		{
			return getScheduledStopTime();
		}
	}
	
	public void setEstimatedStopTime(long time)
	{
		Calendar c = Calendar.getInstance();
		c.setTimeInMillis(time);
		setEstimatedStopTime(c);
	}

	public void setEstimatedStopTime(Calendar c)
	{
		this.estimatedStopTime = c;
	}

	public Calendar getScheduledStopTime()
	{
		return scheduledStopTime;
	}

	public void setScheduledStopTime(long time)
	{
		Calendar c = Calendar.getInstance();
		c.setTimeInMillis(time);
		setScheduledStopTime(c);
	}
	
	public void setScheduledStopTime(Calendar c)
	{
		this.scheduledStopTime = c;
	}

	public boolean isDeparted()
	{
		return departed;
	}

	public void setDeparted(boolean b)
	{
		this.departed = b;
	}

	public String getShortsign()
	{
		return shortsign;
	}

	public void setShortsign(String s)
	{
		this.shortsign = s;
	}

	public String getRoute()
	{
		return route;
	}

	public void setRoute(String r)
	{
		this.route = r;
	}

	public BlockPosition getBlockPosition()
	{
		return blockPosition;
	}

	public void setBlockPosition(BlockPosition bp)
	{
		this.blockPosition = bp;
	}

	public boolean isDetour()
	{
		return detour;
	}

	public void setDetour(boolean b)
	{
		this.detour = b;
	}
	
	public boolean isOnTime()
	{
		if (this.getEstimatedStopTime() == null)
		{
			return true;
		}
		else
		{
			long diff = getScheduledStopTime().getTimeInMillis() - getEstimatedStopTime().getTimeInMillis();
			
			return ( Math.abs(diff) < ONE_MINUTE );
		}
	}

	public boolean isArrivingWithin(long milliseconds)
	{
		Calendar stopTime = getStopTime();
		
		if (stopTime == null)
		{
			return false;
		}
		
		Calendar now = Calendar.getInstance();
		
		long diff = stopTime.getTimeInMillis() - now.getTimeInMillis();
		
		if (diff < 0)
		{
			return false;
		}
		else
		{
			return (diff <= milliseconds);
		}
	}
	
	public String toString()
	{
		return "Route: " + this.getRoute();
	}

	/**
	 * 
	 * @return number of minutes that you'll need to wait for this bus to arrive
	 * 
	 */
	public Long getWaitTimeInMinutes()
	{
		Calendar now = Calendar.getInstance();

		Calendar stopTime = getStopTime();
		
		if (stopTime == null)
		{
			return null;
		}
		else if (stopTime.before(now))
		{
			return null;
		}
		else
		{
			long diff = stopTime.getTimeInMillis() - now.getTimeInMillis();
			
			return (diff / ONE_MINUTE);
		}
		
	}
	
	public boolean isScheduled()
	{
		if (this.getStatus() == null)
		{
			return false;
		}
		else
		{
			return "scheduled".equalsIgnoreCase(this.getStatus());
		}
	}
	
	public boolean isEstimated()
	{
		if (this.getStatus() == null)
		{
			return false;
		}
		else
		{
			return "estimated".equalsIgnoreCase(this.getStatus());
		}
	}

}
